import java.awt.Color;
import java.awt.Graphics;
import java.lang.Math;

public class Hex {
	private final int[] location;//hex's location
	private Sprite occupant; //Whatever is currently in the hex.  Only one occupant per hex,
	//layers are obtained via a 3 dimensional grid.
	private int[] drawXMatrix;
	private int[] drawYMatrix;//for drawing the outline of the Hex
	//Kept as a float for accuracy,  cast to int on drawing
	int xLoc; //The center x/y
	int yLoc;
	
	
	public Hex()
	{
		occupant = new NullSprite();
		location = new int[3];
		drawXMatrix = new int[6];
		drawYMatrix = new int[6];
	}
	
	public Hex(int r,int c,int d){
		occupant = new NullSprite();
		location = new int[3];
		location[0] = r;
		location[1] = c;
		location[2] = d;

		drawXMatrix = new int[6];
		drawYMatrix = new int[6];
	}
	
	/**
	 * Update the movement flags.
	 * 
	 */
	public void setOccupantMoved(boolean moved){
		if(!isEmpty() && occupant instanceof MobileSprite)
		{	MobileSprite o = (MobileSprite)occupant;
			o.setMoved(moved);
		}
	}
	/**
	 * Takes the HexGrid and moves the occupant if able
	 * 
	 */
	public void moveOccupant(HexGrid world){
		if(!isEmpty() && occupant instanceof MobileSprite)
		{	MobileSprite o = (MobileSprite)occupant;
			o.move(world);
		}
	}
	
	/**
	 * Returns true if the hex is empty.
	 * 
	 */
	public boolean isEmpty()
	{
		return occupant instanceof NullSprite;
	}
	
	public void setOccupant(HexGrid world){
		if(!isEmpty() && occupant instanceof MobileSprite)
		{	MobileSprite o = (MobileSprite)occupant;
			o.setParameters(world);
		}
	}
	
	/**
	 * Tries to move a Sprite into a Hex.  If the move is successful
	 * returns true, else false.
	 */
	public boolean moveIntoHex(Sprite newOccupant)
	{
		if(isEmpty())
		{
			occupant = newOccupant;
			occupant.setLocation(location);
			return true;
		}
		else
			return false;
	}
	
	/**
	 * A toString method for indexing and debugging purposes.
	 */
	public String toString(){
		return "Hex@"+String.format("%d",location[0])+"_"+String.format("%d",location[1])+"_"+String.format("%d",location[2]);
	}
	
	/**Removes the specified sprite from the hex.  If the sprite was found
	 * in the Hex, we return true, else false.
	 */
	public boolean leaveHex()
	{
		if(isEmpty())
			return false;
		else
		{
			occupant = new NullSprite();
			return true;
		}
	}
	
	/**
	 * Takes the graphics class and draws the hex outline and the occupant inside the Hex.
	 * 
	 */
	public void drawHex(Graphics g)
	{
		
		if(!isEmpty()) //Do not attempt to draw the NullSprite.  It has no image.
		{
			occupant.drawSprite(g, xLoc, yLoc); //Draw or animate whatever's in sprite

		}
		g.setColor(Color.WHITE);
		g.drawPolygon(drawXMatrix, drawYMatrix, 6);
	}
	
	/**
	 * Takes the graphics class and draws a highlighted Hex.
	 * 
	 */
	public void drawHighlightHex(Graphics g)
	{
		g.setColor(Color.GREEN);
		g.fillPolygon(drawXMatrix,drawYMatrix,6);
		if(!isEmpty()) //Do not attempt to draw the NullSprite.  It has no image.
		{
			occupant.drawSprite(g, xLoc, yLoc); //Draw or animate whatever's in sprite
		}
	}
	
	public int manhattanDistance(Hex b){
		return Math.abs(b.location[0] - this.location[0]) + 
		Math.abs(b.location[1] - this.location[1]) + 
		Math.abs(b.location[2] - this.location[2]); 
	}

	/**
	 * Returns the x/y/z location of the Hex
	 * 
	 */
	public final int[] getLocation(){
		return this.location;
	}
	
	/**Give the center of the Hex, setDrawMatrix creates the 6 points of the Hex for drawing.
	 * This should be called only once at initalization.
	 * 
	 */
	public void setDrawMatrix(int x, int y, int radius)
	{

		xLoc = x - radius/2;
		yLoc = y - radius/2;
		
		double Xoffset = Math.cos(Math.PI/3) * radius; //Hex is regular.  Degree is always 60
		double Yoffset = Math.sin(Math.PI/3) * radius;
		
		//Starting at the left flat corner assign the pixels of this Hex.
		drawXMatrix[0] = (int)(x - radius);
		drawYMatrix[0] = (int)(y);
		
		
		drawXMatrix[1] = (int)(x - Xoffset);
		drawYMatrix[1] = (int)(y - Yoffset);
		
		drawXMatrix[2] = (int)(x + Xoffset);
		drawYMatrix[2] = (int)(y - Yoffset);
		
		drawXMatrix[3] = (int)(x + radius);
		drawYMatrix[3] = (int)(y);
		
		drawXMatrix[4] = (int)(x + Xoffset);
		drawYMatrix[4] = (int)(y + Yoffset);
		
		drawXMatrix[5] = (int)(x - Xoffset);
		drawYMatrix[5] = (int)(y + Yoffset);
		
	}
}
